<template>
  <div v-loading="loading" class="main-container">
    <el-page-header @back="$router.go(-1)">
      <template #content>
        <div style="display: flex; align-items: center">
          <span class="text-sm mr-2">形象上传</span>
        </div>
      </template>
    </el-page-header>

    <div class="content-wrapper">
      <div class="uploader-box">
        <el-upload
          class="avatar-uploader"
          :show-file-list="false"
          :before-upload="beforeAvatarUpload"
          :http-request="handleUploadRequest"
        >
          <div v-if="localImgUrl.length > 5">
            <img
              :src="localImgUrl"
              style="max-width: 300px; max-height: 450px; border-radius: 8px"
            />
          </div>
          <div v-else class="uploader-content">
            <el-icon class="avatar-uploader-icon"><Plus /></el-icon>
            <span class="upload-text">点击上传形象图片</span>
            <span class="upload-desc">建议尺寸：600×900像素</span>
          </div>
        </el-upload>

        <!-- 上传完成后的操作按钮 -->
        <div v-if="localImgUrl.length > 5" class="action-buttons">
          <el-button @click="handleCancel" type="default" class="cancel-action-btn">
            取消
          </el-button>
          <el-button @click="handleConfirm" type="primary" class="confirm-action-btn">
            确认
          </el-button>
        </div>
      </div>
    </div>

    <!-- 裁剪弹窗 -->
    <el-dialog
      v-model="dialogVisible"
      title="形象编辑器"
      :width="isMobile ? '100%' : '80%'"
      :fullscreen="isMobile"
      @closed="handleDialogClose"
      custom-class="cropper-dialog"
      :close-on-click-modal="false"
    >
      <div class="cropper-wrapper">
        <div class="cropper-container">
          <img ref="imageRef" :src="imageUrl" alt="待裁剪图片" />
        </div>
      </div>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false" class="cancel-btn">取消</el-button>
          <el-button type="primary" @click="cropImage" class="confirm-btn"
            >好了！</el-button
          >
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts">
import { Options, Vue } from "vue-class-component";
import Cropper from "cropperjs";
import "cropperjs/dist/cropper.css";
import { ElDialog, ElButton, ElNotification } from "element-plus";
import { Plus } from "@element-plus/icons-vue";
import { callApi } from "@/tool/server";

@Options({
  components: {
    ElDialog,
    ElButton,
    Plus,
    ElNotification,
  },
})
export default class ImageEditor extends Vue {
  private declare $message: any;
  private cropper: Cropper | null = null;
  private imageUrl = "";
  private dialogVisible = false;
  private loading = false;
  private localImgUrl = "";
  private readonly width = 600;
  private readonly height = 900;

  private initCropper() {
    const image = this.$refs.imageRef as HTMLImageElement;
    if (this.cropper) {
      this.cropper.destroy();
    }
    this.cropper = new Cropper(image, {
      aspectRatio: this.width / this.height,
      viewMode: 1,
      dragMode: "move",
      autoCrop: true,
    });
  }

  private async cropImage() {
    if (!this.cropper) return;
    this.loading = true;
    this.dialogVisible = false;
    const canvas = this.cropper.getCroppedCanvas({
      width: this.width,
      height: this.height,
    });
    if (!canvas) {
      console.error("无法获取裁剪画布");
      this.loading = false;
      return;
    }
    canvas.toBlob(
      async (blob: Blob | null) => {
        if (!blob) {
          this.loading = false;
          return;
        }
        const arrayBuffer = await blob.arrayBuffer();
        const uint8Array = new Uint8Array(arrayBuffer);
        try {
          callApi("UploadImg", {
            imgBuf: uint8Array,
          }).then(async (res) => {
            if (!res) {
              this.loading = false;
              return;
            }
            this.localImgUrl = res.imgUrl;
            this.loading = false;
          });
        } catch (error) {
          console.error("上传失败:", error);
          ElNotification.error({
            title: "上传失败",
            message: "上传失败，请重试",
          });
          this.loading = false;
        }
      },
      "image/jpeg",
      0.9
    );
  }

  private handleCancel() {
    this.localImgUrl = "";
    ElNotification.info({
      title: "已取消",
      message: "已恢复到初始状态",
    });
  }

  private async handleConfirm() {
    if (!this.localImgUrl) {
      this.$message.error("请先上传图片");
      return;
    }
    this.loading = true;
    try {
      // 调用上传形象接口
      const res = await callApi("mod/CreateShow", {
        url: this.localImgUrl,
      });
      if (res) {
        ElNotification.success({
          title: "形象上传成功",
          message: "上传完成，等待审核",
        });
        this.$router.push("/");
      } else {
        ElNotification.error({
          title: "上传失败",
          message: "形象上传失败，请重试",
        });
      }
    } catch (error) {
      console.error("形象上传失败:", error);
      ElNotification.error({
        title: "上传失败",
        message: "形象上传失败，请重试",
      });
    } finally {
      this.loading = false;
    }
  }

  private handleDialogClose() {
    if (this.cropper) {
      this.cropper.destroy();
      this.cropper = null;
    }
    this.imageUrl = "";
  }

  private get isMobile() {
    return window.innerWidth <= 768;
  }

  private beforeAvatarUpload(file: File) {
    const isImage = file.type.startsWith("image/");
    const isLt10M = file.size / 1024 / 1024 < 10;
    if (!isImage) {
      this.$message.error("只能上传图片格式!");
      return false;
    }
    if (!isLt10M) {
      this.$message.error("图片大小不能超过10MB!");
      return false;
    }
    this.handleFile(file);
    return false;
  }

  private handleFile(file: File) {
    const reader = new FileReader();
    reader.onload = (e) => {
      this.imageUrl = e.target?.result as string;
      this.dialogVisible = true;
      this.$nextTick(() => this.initCropper());
    };
    reader.readAsDataURL(file);
  }

  private handleUploadRequest(request: any) {
    // 处理上传请求的逻辑
  }
}
</script>

<style scoped>
.main-container {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.content-wrapper {
  flex: 1;
  display: flex;
  position: relative;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px 20px 100px 20px;
}

.uploader-box {
  max-width: 400px;
  width: 100%;
}

.action-buttons {
  display: flex;
  gap: 12px;
  justify-content: center;
  margin-top: 20px;
}

.cancel-action-btn {
  background: #f0f2f5;
  color: #606266;
  border-color: #dcdfe6;
}

.confirm-action-btn {
  background: #409eff;
  transition: all 0.3s;
}

.confirm-action-btn:hover {
  background: #66b1ff;
  transform: translateY(-1px);
}

.action-buttons {
  display: flex;
  gap: 12px;
  justify-content: center;
  margin-top: 20px;
}

.cancel-action-btn {
  background: #f0f2f5;
  color: #606266;
  border-color: #dcdfe6;
}

.confirm-action-btn {
  background: #409eff;
  transition: all 0.3s;
}

.confirm-action-btn:hover {
  background: #66b1ff;
  transform: translateY(-1px);
}

.cropper-wrapper {
  position: relative;
  height: 75vh;
  background: #f8f9fa;
  border-radius: 8px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

.cropper-container {
  width: 90%;
  height: 90%;
  margin: 2% auto;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.cropper-container img {
  max-width: 100%;
  max-height: 80vh;
  object-fit: contain;
}

/* 调整弹窗内裁剪区域样式 */
:deep(.el-dialog__body) {
  padding: 10px;
  max-height: 85vh;
  overflow: hidden;
}

/* 移动端全屏样式 */
@media (max-width: 768px) {
  :deep(.cropper-dialog) {
    border-radius: 0;
  }

  .cropper-container {
    width: 98%;
    height: 95%;
    margin: 1% auto;
  }

  :deep(.el-dialog__body) {
    padding: 8px;
    height: calc(100vh - 100px);
  }

  .cropper-container img {
    max-height: 80vh !important;
  }
}

/* 固定弹窗底部按钮 */
:deep(.el-dialog__footer) {
  position: sticky;
  bottom: 0;
  background: white;
  z-index: 1000;
  padding: 10px 20px;
  box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.1);
}

/* 弹窗整体美化 */
:deep(.cropper-dialog) {
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

/* 标题样式优化 */
:deep(.el-dialog__header) {
  border-bottom: 1px solid #eee;
  margin: 0 20px;
  padding: 16px 0;
}

:deep(.el-dialog__title) {
  font-size: 18px;
  color: #333;
  font-weight: 500;
}

/* 底部按钮优化 */
.dialog-footer {
  display: flex;
  gap: 12px;
  justify-content: flex-end;
}

.cancel-btn {
  background: #f0f2f5;
  color: #606266;
  border-color: #dcdfe6;
}

.confirm-btn {
  background: #409eff;
  transition: all 0.3s;
}

.confirm-btn:hover {
  background: #66b1ff;
  transform: translateY(-1px);
}

.avatar-uploader {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 400px;
  padding: 20px 0;
}

.uploader-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
  height: 100%;
}

.avatar-uploader-icon {
  font-size: 48px;
  color: var(--el-color-primary);
  width: 200px;
  height: 200px;
  border: 2px dashed var(--el-border-color);
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s;
  background: transparent !important;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
}

.upload-text {
  color: var(--el-text-color-regular);
  font-size: 16px;
  font-weight: 500;
}

.upload-desc {
  color: var(--el-text-color-secondary);
  font-size: 14px;
}

/* 悬停效果 */
:deep(.avatar-uploader .el-upload) {
  border: none !important;
}

:deep(.avatar-uploader:hover .avatar-uploader-icon) {
  border-color: var(--el-color-primary);
  transform: translateY(-5px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

:deep(.el-upload:focus) {
  outline: none !important;
}

:deep(.el-upload) {
  outline: none !important;
  -webkit-tap-highlight-color: transparent !important;
}

:deep(.el-upload:active) {
  background: transparent !important;
}
</style>
